<script setup lang="ts">
import { onMounted, onUnmounted } from "vue"

class VideoWithBackground {
  video
  canvas
  step
  ctx

  constructor(videoId, canvasId) {
    const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)")
    if (!mediaQuery.matches) {

      onMounted(() => {
        this.video = document.getElementById(videoId)
        this.canvas = document.getElementById(canvasId)
        this.init()
      })

      onUnmounted(() => {
        // 这里不需手动销毁
        // this.cleanup()
      })
    }

  }

  draw = () => {
    this.ctx.drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height)
  }

  drawLoop = () => {
    this.draw()
    this.step = window.requestAnimationFrame(this.drawLoop)
  }

  drawPause = () => {
    window.cancelAnimationFrame(this.step)
    this.step = undefined
  }

  init = () => {
    this.ctx = this.canvas.getContext("2d")
    this.ctx.filter = "blur(1px)"

    this.video.addEventListener("loadeddata", this.draw, false)
    this.video.addEventListener("seeked", this.draw, false)
    this.video.addEventListener("play", this.drawLoop, false)
    this.video.addEventListener("pause", this.drawPause, false)
    this.video.addEventListener("ended", this.drawPause, false)
  }

  cleanup = () => {
    this.video.removeEventListener("loadeddata", this.draw)
    this.video.removeEventListener("seeked", this.draw)
    this.video.removeEventListener("play", this.drawLoop)
    this.video.removeEventListener("pause", this.drawPause)
    this.video.removeEventListener("ended", this.drawPause)
  }
}

onMounted(() => {
  const el = new VideoWithBackground("js-video", "js-canvas")
})

</script>

<template>
  <div class="box">
    <section class="wrapper">
      <video controls muted class="video" id="js-video" src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
      <canvas width="10" height="6" aria-hidden="true" class="canvas" id="js-canvas"></canvas>
    </section>
  </div>
</template>

<style scoped lang="scss">
$colorBackground: rgb(15, 15, 15);

.box {
  margin: 0 auto;
  background-color: $colorBackground;
  min-height: 100%;
}

/* Required styles */

*,
*::before,
*::after {
  box-sizing: border-box;
}

.video,
.canvas {
  display: block;
  width: 100%;
  height: auto;
  margin: 0;
}

.wrapper {
  position: relative;
  box-shadow: inset 0 0 4rem 4.5rem $colorBackground;
  max-width: 90%;
  height: 400px;
  margin: 0 auto;
}

.canvas {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 5;
  width: 100%;
  height: 100%;
  opacity: 0.4;
}

.video {
  padding: 3rem;
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  z-index: 10;
}

@media (prefers-reduced-motion: reduce) {
  .canvas {
    display: none !important;
  }
}
</style>